home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / graph_alg / _strongcomp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  3.1 KB  |  124 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _strongcomp.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. /*******************************************************************************
  17. *                                                                              *
  18. *  STRONG_COMPONENTS (strong connected components)                             *
  19. *                                                                              *
  20. *******************************************************************************/
  21.  
  22.  
  23. #include <LEDA/graph_alg.h>
  24.  
  25. static void scc_dfs(const graph& G, node v, node_array<int>& compnum,
  26.                                             node_data<int>& dfsnum,
  27.                                             node_list& unfinished,
  28.                                             list<node>& roots,
  29.                                             int& count1, int& count2 );
  30.  
  31.  
  32. int STRONG_COMPONENTS(const graph& G, node_array<int>& compnum)
  33. {
  34.   // int STRONG_COMPONENTS(graph& G, node_array<int>& compnum)
  35.   // computes strong connected components (scc) of digraph G
  36.   // returns m = number of scc 
  37.   // returns in node_array<int> compnum for each node an integer with
  38.   // compnum[v] = compnum[w] iff v and w belong to the same scc
  39.   // 0 <= compnum[v] <= m-1 for all nodes v
  40.  
  41.   list<node>     roots;
  42.   node_list      unfinished;
  43.   node_data<int> dfsnum(G,-1);
  44.  
  45.   int count1 = 0; 
  46.   int count2 = 0;
  47.  
  48.   node v;
  49.  
  50.   forall_nodes(v,G) 
  51.       if (dfsnum[v] == -1) 
  52.        scc_dfs(G,v,compnum,dfsnum,unfinished,roots,count1,count2);
  53.  
  54.   return count2;
  55. }
  56.  
  57.  
  58. static void scc_dfs(const graph& G, node v, node_array<int>& compnum,
  59.                                             node_data<int>& dfsnum,
  60.                                             node_list& unfinished,
  61.                                             list<node>& roots,
  62.                                             int& count1, int& count2 )
  63. {
  64.   node w;
  65.  
  66.   dfsnum[v] = ++count1;
  67.   unfinished.push(v);
  68.   roots.push(v);
  69.  
  70.   forall_adj_nodes(w,v)
  71.     { if (dfsnum[w]==-1) 
  72.        scc_dfs(G,w,compnum,dfsnum,unfinished,roots,count1,count2);
  73.       else 
  74.        if (unfinished(w))
  75.         while (dfsnum[roots.head()]>dfsnum[w])  roots.pop();
  76.      }
  77.  
  78.   if (v==roots.head()) 
  79.    { do { w=unfinished.pop();
  80.           /* w is an element of the scc with root v */
  81.           compnum[w] = count2;
  82.          } while (v!=w);
  83.      count2++;
  84.      roots.pop(); 
  85.     }
  86. }
  87.  
  88.  
  89.  
  90. int STRONG_COMPONENTS1(graph& G, node_array<int>& compnum)
  91.   node v,w;
  92.   int n = G.number_of_nodes();
  93.   int count = 0;
  94.  
  95.   node* V = new node[n+1];
  96.  
  97.   list<node> S;
  98.   node_array<int> dfs_num(G);
  99.   node_array<int> compl_num(G);
  100.   node_array<bool> reached(G,false);
  101.  
  102.   DFS_NUM(G,dfs_num,compl_num);
  103.  
  104.   forall_nodes(v,G) V[compl_num[v]] = v;
  105.  
  106.   G.rev();
  107.  
  108.   for(int i=n; i>0; i--)
  109.    { if ( !reached[V[i]] ) 
  110.       { S = DFS(G,V[i],reached);
  111.         forall(w,S) compnum[w] = count;
  112.         count++;
  113.        }
  114.     }
  115.  
  116.  delete V;
  117.  
  118.  return count;
  119.    
  120.  }
  121.  
  122.